import networkx as nx
from celery import Celery
from app.tasks.workflow_tasks import execute_node
from app.config import config

celery = Celery('workflow', broker=config['queue']['redis']['url'])

class WorkflowExecutor:
    def __init__(self, workflow):
        self.workflow = workflow
        self.graph = self._build_dag()

    def _build_dag(self):
        G = nx.DiGraph()
        for node_id, node_data in self.workflow.nodes.items():
            G.add_node(node_id, data=node_data)
        for conn in self.workflow.connections:
            G.add_edge(conn["output"], conn["input"])  # Drawflow uses "output" and "input"
        if not nx.is_directed_acyclic_graph(G):
            raise ValueError("Workflow contains cycles")
        return G

    def run_async(self):
        sorted_nodes = list(nx.topological_sort(self.graph))
        task_chain = None
        for node_id in sorted_nodes:
            task = execute_node.s(node_id, self.graph.nodes[node_id]['data'])
            task_chain = task if not task_chain else task_chain | task
        result = task_chain.apply_async()
        return result.id